#include"String.h"

string::string(const char* str)
{
    int len=strlen(str);
    _str=new char[len+1];
    memcpy(_str,str,len);
    _str[len]='\0';

    _size=len;
    _capacity=_size*2;
}
string::string(const string& s)//注意参数类型必须是同类型的引用
{
    _str=new char[s._capacity+1];
    memcpy(_str,s._str,s._size+1);//把末尾的'\0'也顺便拷贝进去

    _size=s._size;
    _capacity=s._capacity;
}
string::~string()
{
    delete[] _str;
    _str=nullptr;
    _size=_capacity=0;
}

const char* string::c_str()const
{
    return _str;
}
size_t string::size()const
{
    return _size;
}
size_t string::capacity()const
{
    return _capacity;
}
//const对象无法访问，返回值可以修改
char& string::operator[](int pos)
{
    if(pos<0 || pos>=_size)std::cout<<"数组越界访问！！"<<std::endl;

    else return _str[pos];
}
//const对象能够访问，返回值无法修改
const char& string::operator[](int pos)const 
{
    if(pos<0 || pos>=_size)std::cout<<"越界访问,非法！！"<<std::endl;

    else return _str[pos];
}

void string::reserve(int n)
{
    if (n > _capacity)
    {
        int new_capacity = _capacity == 0 ? 4 : n;
        char* tmp = new char[new_capacity + 1];//注意：这里用的是[]，不是()！！！
        memcpy(tmp, _str, _size + 1);//把_str里的'\0'也拷贝给tmp

        delete[] _str;
        _str = tmp;
        _capacity = new_capacity;
    }
}
void string::resize(size_t n,char ch)
{
    if(n>_capacity)
    {
        reserve(n);
    }
    for(int i=0;i<n;i++)
        _str[i]=ch;
    _str[n]='\0';
    _size=n;
}

void string::push_back(char ch)
{
    if(_size==_capacity)
        reserve(_capacity*2);
    
    _str[_size++]=ch;
    _str[_size]='\0';
}
void string::insert(int pos,char ch)
{
    if(pos<0 || pos>_size)std::cout<<"越界访问，非法！！"<<std::endl;

    if(_size==_capacity)
        reserve(_capacity*2);

    int end=_size;
    while(end>=pos)
    {
        _str[end+1]=_str[end];
        end--;
    }
    _str[pos]=ch;
    _size++; 
}
void string::insert(int pos,const char* str)
{   
    if(pos<0 || pos>_size)std::cout<<"越界访问，非法！！"<<std::endl;

    int len=strlen(str);
    if(_size+len > _capacity)
        reserve(_size+len);

    int end=_size;

    while(end>=pos)
    {
        _str[end+len]=_str[end];
        end--;
    }
    for(int i=pos;i<len+pos;i++)
    {
        _str[i]=str[i-pos];
    }

    _size+=len;
}
void string::append(const char* str)
{
    int len=strlen(str);
    if(len+_size>_capacity)
        reserve(len+_size);

    strcat(_str+_size,str);
    _size+=len;
}
void string::clear()
{
    _size=0;
    _str[_size]='\0';
}
void string::erase(int pos,size_t len)
{
    if(len==npos || pos+len>=_size)//注意：把len==npos写前面，否则可能导致pos+len值溢出
    {
        _size=pos;
        _str[_size]='\0';
    }
    else 
    {
        while(pos+len<=_size)
        {
            _str[pos]=_str[pos+len];
            pos++;
        }
        _size-=len;
    }
}
size_t string::find(const char* str,size_t pos)
{
    int len=strlen(str);
    if(len>_size-pos)return -1;

    for(int i=pos;i+len<=_size;i++)
    {
        int _index=i,index=0;
        while(_index<_size && index<len && _str[_index]==str[index])
            _index++,index++;
        if(index==len)return i;
    }
    return -1;
}
string string::substr(size_t pos,size_t len)
{
    string tmp;
    if(len==npos || pos+len>=_size)len=_size-pos;
    for(int i=pos;i<pos+len;i++)
        tmp+=_str[i];
    return tmp;//需要用到拷贝构造
}

string& string::operator+=(char ch)
{
    this->push_back(ch);
    return *this;
}
string& string::operator+=(const char* str)
{
    this->append(str);
    return *this;
}
string& string::operator=(string str)
{
    delete[] _str;
    _str=new char[str.capacity()+1];
    memcpy(_str,str.c_str(),str.size()+1);//把末尾的'\0'顺便拷贝过去
    _size=str.size();
    _capacity=str.capacity();

    return *this;
}

//全局函数，而非类的成员函数
std::ostream& operator<<(std::ostream& out,string& str)
{
    for(int i=0;i<str.size();i++)
        std::cout<<str[i];
    return out;
}
std::istream& operator>>(std::istream& in,string& str)
{
    str.clear();//先清空原有数据

    char ch=in.get();//将输入的数据放在一个缓冲区内

    while(ch==' '||ch=='\n')ch=in.get();//排除首空格和'\n'情况

    while(ch!=' ' && ch!='\n')
    {
        str+=ch;
        ch=in.get();
    }

    return in;
}

bool string::operator<(const string& str)
{
    size_t len1=0,len2=0;

    while(len1<_size && len2<str.size())
    {
        if(_str[len1]<str[len2])return true;
        else if(_str[len1]>str[len2])return false;
        else len1++,len2++;
    }
    if(_size>str.size())return true;

    return false;
}
bool string::operator==(const string& str)
{
    return _size==str.size() && _capacity==str.capacity()?(memcmp(_str,str.c_str(),_size)==0):false;
}
bool string::operator<=(const string& str)
{
    return *this<str || *this==str;
}
bool string::operator>(const string& str)
{
    return !(*this<=str);
}
bool string::operator>=(const string& str)
{
    return !(*this<str);
}
bool string::operator!=(const string& str)
{
    return !(*this==str);
}